<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

/**
 * 分类树辅助函数
 */

/**
 * 引用算法生成层级树数组
 *
 * 把返回的数据集转换成Tree
 * 巧妙使用php引用实现无限分类
 *
 * @param array $list 要转换的数据集
 * @param string $pk id标记字段
 * @param string $pid 父id标记字段
 * @param string $_child 子节点标记字段
 * @param int $root 要获取数的根节点数值
 *
 * @return array
 * @author 麦当苗儿 <zuojiazi@vip.qq.com>
 */
function list_to_tree($list, $pk = 'id', $pid = 'pid', $_child = '_child', $root = 0) {
    // 创建Tree
    $tree = array();
    if (is_array($list)) {
        // 创建基于主键的数组引用
        $refer = array();
        foreach ($list as $key => $data) {
            $refer[$data[$pk]] = &$list[$key];
        }
        foreach ($list as $key => $data) {
            // 判断是否存在parent
            $parentId = $data[$pid];
            if ($root == $parentId) {
                $tree[$data[$pk]] = &$list[$key];
            } else {
                if (isset($refer[$parentId])) {
                    $parent = &$refer[$parentId];
                    $parent[$_child][$data[$pk]] = &$list[$key];
                }
            }
        }
    }
    return $tree;
}

/**
 * 递归算法把上面list_to_tree()生成的层级树转换为列表
 *
 * 将list_to_tree的树还原成列表
 *
 * @param  array $tree 原来的树
 * @param  string $pk id标记字段
 * @param  bool $add_child 列表数组是否附加子节点
 * @param  string $_child 孩子节点的键
 * @param  int $_depth 节点深度 （从0开始，用于输出节点时缩进）
 * @param  array &$list 过渡用的中间数组，
 *
 * @return array                返回排过序的列表数组
 * @author yangweijie <yangweijiester@gmail.com>
 */
function tree_to_list($tree, $pk = 'id', $add_child = false, $_child = '_child', $_depth = 0, &$list = array()) {
    if (is_array($tree)) {
        foreach ($tree as $key => $val) {
            $refer = $val;
            $refer['_depth'] = $_depth;
            if (isset($refer[$_child])) {
                if (!$add_child) unset($refer[$_child]);
                $list[$val[$pk]] = $refer;
                tree_to_list($val[$_child], $pk, $add_child, $_child, $_depth + 1, $list);
            } else {
                $list[$val[$pk]] = $refer;
            }
        }
    }
    return $list;
}

/**
 * 找父母（迭代算法）
 *
 * 非常快的算法，仅可用于找父母（单支线，找儿子是多支线）
 * 用途：面包屑导航
 *
 * @param array $arr 数据列表
 * @param int $id
 * @param string $id_field id字段名称
 * @param string $pid_field fid字段名称
 * @return array
 */
function list_find_parents($arr, $id, $id_field = 'id', $pid_field = 'pid') {
    if (empty($arr)) return array();

    //如果$arr数组不是以id值作为健名，则重组以id值做为键名的数组
    if (isset($arr[0]) && !empty($arr[0])) {
        $_arr = array();
        foreach ($arr as $val) {
            $_arr[$val[$id_field]] = $val;
        }
        $arr = &$_arr;
    }

    $return = array();
    while ($id != 0) {
        $return[$id] = $arr[$id];
        $id = $arr[$id][$pid_field];
    }
    $return = array_reverse($return, true);
    return $return;
}

/* End of file Tree_helper.php */
/* Location: ./helpers/Tree_helper.php */
